I've created a Slider with labels in react. When the user moves the Slider the numbers underneath get highlighted, I achieved it by giving the number class like this.
<span
className={scaleHighlightClass[index]}
key={index}
ref={scaleElement}
onClick={() => handleClickOnScale(index)}
>
The scaleHighlightClass array uses a Hook like so:
const [scaleHighlightClass, setScaleHighlightClass] = useState<string[]>(["selected"])
When the user moves the slider (which is a input with type=range) this function gets triggerd.
const highlightSelected = (selectedNumber) => {
// Reset all others
for (var i = 0; i < scaleHighlightClass.length; i++) {
scaleHighlightClass[i] = ""
}
// Set the clicked/slided to as selected
setScaleHighlightClass([...scaleHighlightClass])
}
It does work as expected but when using the Slider it triggers a re-render for every number it passes by. It is intended since I want to have this effect, but the question is, is this effective in terms of performance?
Is there a better way to change classes dynamically.
You're calling the function way to many times this way, maybe you can use debounce to decrease the number of times the code gets executed.
import debounce from 'lodash.debounce';
const debouncedSave = debounce(() => handleClickOnScale(index), 1000);
Save the current selected index in the state:
const [scaleHighlightIndex, setScaleHighlightIndex] = useState<number>(0)
The item has the selected class if it's index matches the scaleHighlightIndex. When you need to select another item, just pass the the current index to setScaleHighlightIndex directly:
<span
className={index === scaleHighlightIndex ? 'selected' : ''}
key={index}
ref={scaleElement}
onClick={() => setScaleHighlightIndex(index)}
>
You can use debounce or throttle to prevent too many re-renders, but before doing so profile, and see that you actually have a performance problem.